<?php

class XMLStreamWriter
{
	function __construct($fname, $version='1.0', $encoding='windows-1251')
	{
		$this->f = fopen($fname,'w');
		if (!$this->f)
		{
			throw new Exception("Can not open/create file $fname");
		}
		fwrite($this->f,"<?xml version=\"$version\" encoding=\"$encoding\"?>");
	}
	
	function __destruct()
	{
		fclose($this->f);
	}
	
	public function flush()
	{
		fflush($this->f);
	}

	public function setIndent($indent)
	{
		$this->indent = $indent;
	}
	
	public function writeElement($name, $content=null)
	{
		$this->closeStartTag(true);
		if ($content && !empty($content))
		{
			$this->writeRaw("<$name>".$this->xmlconvert($content)."</$name>");
		}
		else
		{
			$this->writeRaw("<$name/>");
		}
	}
	
	public function startElement($name)
	{
		$this->closeStartTag(true);

		$this->writeRaw("<$name");		
		$this->startedElements[] = $name;
		$this->tagOpen = true;
	}
	
	public function writeAttribute($name, $val)
	{
		if ($this->tagOpen)
		{
			$this->write(" $name=\"".$this->xmlconvert($val).'"');
		}
	}
	
	public function text($content)
	{
		$this->closeStartTag(false);
		$this->write($this->xmlconvert($content));
	}
	
	public function endElement()
	{
		$tag = array_pop($this->startedElements);
		if ($tag)
		{
			if ($this->tagOpen)
			{
				$this->write("/>");
			}
			else
			{
				if ($this->needIndent)
				{
					$this->writeRaw("</".$tag.">");
				}
				else
				{
					$this->write("</".$tag.">");
				}
			}
			$this->tagOpen = false;
		}
	}
	
	
	public function writeRaw($s)
	{
		if (!is_null($this->indent))
		{
			fwrite($this->f,"\n".str_repeat($this->indent,count($this->startedElements)));
		}
		fwrite($this->f,$s);
	}
	
	
	
	private function xmlconvert($s)
	{
		return str_replace("'",'&apos;',htmlspecialchars($s));
	}
	
	private function write($s)
	{
		fwrite($this->f, $s);
	}
	
	private function closeStartTag($needIndent)
	{
		if ($this->tagOpen)
		{
			$this->write('>');
			$this->tagOpen = false;
		}
		$this->needIndent = $needIndent;
	}

	private $f = false;
	private $indent = null;
	private $startedElements = array();
	private $tagOpen = false;
	private $needIndent = false;
};

?>